package com.loooooo.pm2024.utils;

import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jose.crypto.opts.AllowWeakRSAKey;
import io.jsonwebtoken.Claims;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.text.ParseException;
import java.util.Base64;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class JoseJWTUtils {

    static String secret = "124daaq$%^_adada124AADAvtae112224daaq$%^_adada124AADAvtae1122424daaq$%^_adada124AADAvtae1122424daaq$%^_adada124AADAvtae1122424daaq$%^_adada124AADAvtae1122424daaq$%^_adada124AADAvtae1122424daaq$%^_adada124AADAvtae1122424daaq$%^_adada124AADAvtae1122424daaq$%^_adada124AADAvtae112244525884254456fdgthyddertyhvfr45677878ijhhfasfsf";

    static char[] keyPass = "changeit".toCharArray();

    static String createToken(String payloadStr) {
        //创建JWS头，设置签名算法和类型
        JWSHeader jwsHeader = new JWSHeader.Builder(JWSAlgorithm.HS256).
                type(JOSEObjectType.JWT)
                .build();
        //将负载信息封装到Payload中
        Payload payload = new Payload(payloadStr);
        //创建JWS对象
        JWSObject jwsObject = new JWSObject(jwsHeader, payload);
        //创建HMAC签名器
        JWSSigner jwsSigner = null;
        try {
            jwsSigner = new MACSigner(secret);
            //签名
            jwsObject.sign(jwsSigner);
            System.out.println(jwsObject.serialize());
            return jwsObject.serialize();
        } catch (KeyLengthException e) {
            e.printStackTrace();
        } catch (JOSEException e) {
            e.printStackTrace();
        }
        return null;
    }

    static String parseToken(String token, String secret) {
        JWSObject jwsObject = null;
        try {
            jwsObject = JWSObject.parse(token);  //创建HMAC验证器
            JWSVerifier jwsVerifier = new MACVerifier(secret);
            if (!jwsObject.verify(jwsVerifier)) {
                throw new RuntimeException("token签名不合法！");
            }
            String payload = jwsObject.getPayload().toString();
            return payload;
        } catch (ParseException | JOSEException e) {
            e.printStackTrace();
        }
        return null;

    }

    static String createTokenByRSA(String payloadStr, RSAPrivateKey rsaKey) {
        //创建JWS头，设置签名算法和类型
        JWSHeader jwsHeader = new JWSHeader.Builder(JWSAlgorithm.RS256)
                .type(JOSEObjectType.JWT)
                .build();
        //将负载信息封装到Payload中
        Payload payload = new Payload(payloadStr);
        //创建JWS对象
        JWSObject jwsObject = new JWSObject(jwsHeader, payload);
        //创建RSA签名器
        JWSSigner jwsSigner = new RSASSASigner(rsaKey, Collections.singleton(AllowWeakRSAKey.getInstance()));
        //签名
        try {
            jwsObject.sign(jwsSigner);
            return jwsObject.serialize();
        } catch (JOSEException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String createTokenByRSA(String payloadStr) {
        return createTokenByRSA(payloadStr, (RSAPrivateKey) getRSAPrivateKey());
    }

    public static String parseTokenByRSA(String token) {
        return parseTokenByRSA(token, (RSAPublicKey) getRSAPublicKey());

    }

    static String parseTokenByRSA(String token, RSAPublicKey rsaKey) {
        //从token中解析JWS对象
        JWSObject jwsObject = null;
        try {
            jwsObject = JWSObject.parse(token);
            //使用RSA公钥创建RSA验证器
            JWSVerifier jwsVerifier = new RSASSAVerifier(rsaKey);
            if (!jwsObject.verify(jwsVerifier)) {
                throw new RuntimeException("token签名不合法！");
            }
            String payload = jwsObject.getPayload().toString();
            //System.out.println(payload);
            return payload;
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (JOSEException e) {
            e.printStackTrace();
        }
        return null;

    }

    static PrivateKey getRSAPrivateKey() {
        return getRSAPrivateKey(new File("/ytx/cert/cas/cas-private.key"));// RSAUtils.readPrivateKey(new File("/ytx/cert/cas/cas-private.key"));
    }

    static PublicKey getRSAPublicKey() {
        return getRSAPublicKey(new File("/ytx/cert/cas/cas.crt"));
    }

    static PrivateKey getRSAPrivateKey(File file) {
        return RSAUtils.readPrivateKey(file);
    }

    static PublicKey getRSAPublicKey(File file) {
        try {
            return RSAUtils.readPublicKey(new FileInputStream(file));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        // createECCKey();
        //createRSAKey();
//        getPrivateKey();
        Map<String, Object> data = new HashMap<>();
        data.put("a", "ADAD");
        data.put("B", 34565);
        String text = JsonUtils.serializeToString(data);

        System.out.println(Base64.getEncoder().encodeToString(text.getBytes(StandardCharsets.UTF_8)));

        String token = createTokenByRSA(text);
        //token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhIjoiQURBRCIsIkIiOjM0NTY1fQ.I4C3hJUxdDGA9DtD2fAj4v7OgjfhsgM5uT7LRmMyEswzFEk48d2b-lb6TlXkglcR61QHMgmrPMA-Cq9Aibh1TQ";
        System.out.println("RSA:" + token);
        RSAPublicKey publicKey = (RSAPublicKey) getRSAPublicKey();


        String payload = parseTokenByRSA(token, publicKey);
        System.out.println(payload);

        Claims claims = JsonUtils.deserializeFromString(payload,Claims.class);

        Payload payload1= new Payload(payload);

        long endAt = System.currentTimeMillis();

    }

}
